package com.pms.api;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.pms.controller.BaseController;
import com.pms.entity.*;
import com.pms.exception.R;
import com.pms.service.*;
import com.pms.util.DaHaoLockUtil;
import com.pms.util.DateUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;

/**
 * <p>
 * 前端控制器
 * 定时器  删除有效期过时的卡片
 * <p>
 * </p>
 *
 * @author ASUS_B
 * @since 2017-10-17
 */
@RestController
@RequestMapping("/lockCard")
@Api(value = "发卡管理", description = "发卡管理相关接口")
public class LockCardApiController extends BaseController {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private IEntranceDoorService entranceDoorService;
    @Autowired
    IEstateUnitCardService estateUnitCardService;
    @Autowired
    IEstateDoorCardService estateDoorCardService;
    @Autowired
    IEstateLockCardService estateLockCardService;
    @Autowired
    IChargeValueService chargeValueService;
    @Autowired
    private DaHaoLockUtil daHaoLockUtil;
    @Autowired
    private IUnitBuildingService unitBuildingService;
    @ApiOperation(value = "分页查询卡片导入信息")
    @RequestMapping(value = "/readPage", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "pageSize", value = "请求条数", required = false, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "pageNum", value = "请求页数", required = false, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "communityId", value = "社区id", required = true, dataType = "long", paramType = "form"),
            @ApiImplicitParam(name = "unitId", value = "单元id", required = false, dataType = "long", paramType = "form"),
            @ApiImplicitParam(name = "cardNum", value = "卡号-模糊查询", required = false, dataType = "string", paramType = "form"),
            @ApiImplicitParam(name = "cardState", value = "卡号状态(1-已录入(默认),2-待发卡,3-已发卡)", required = false, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "doorId", value = "门id", required = false, dataType = "long", paramType = "form"),
    })
    public R readPage(Integer pageSize, Integer pageNum, Long communityId, Long unitId, String cardNum, Integer cardState, Long doorId) {
        parameterIsNull(communityId, "社区id不能为空");
        if (null == pageNum || pageNum < 1) {
            pageNum = 1;
        }
        if (null == pageSize || pageSize < 1) {
            pageSize = 10;
        }
        if (cardState == null || cardState < 2 || cardState > 3) {
            cardState = 1;
        }
        if (cardState == 1) {//查询已录入
            Page<EstateUnitCard> page = new Page<EstateUnitCard>(pageNum, pageSize);
            Wrapper<EstateUnitCard> wp = new EntityWrapper<EstateUnitCard>();
            wp.eq("community_id", communityId);
            if (unitId != null) {
                wp.eq("unit_id", unitId);
            }
            if (StringUtils.isNotBlank(cardNum)) {
                wp.like("card_num_ten", cardNum);
            }
            wp.orderBy("create_time",false);
            Page<EstateUnitCard> returnPage = estateUnitCardService.selectPage(page, wp);
            return R.ok().put("data", returnPage).putMpPageDescription().putDescription(EstateUnitCard.class);
        }
        if (cardState == 2) {//查询待发卡
            Page<EstateUnitCard> page = new Page<EstateUnitCard>(pageNum, pageSize);
            Wrapper<EstateUnitCard> wp = new EntityWrapper<EstateUnitCard>();
            wp.eq("euc.community_id", communityId);
            String leftJoinWhere = "";
            if (unitId != null) {
                wp.eq("euc.unit_id", unitId);
            }
            if (null != doorId) {
                leftJoinWhere = " and edc.door_id = "+doorId;
            }
            if (StringUtils.isNotBlank(cardNum)) {
                wp.like("euc.cardNumTen", cardNum);
            }
            wp.and("edc.door_card_id is null");
            wp.orderBy("euc.create_time",true);//根据录入时间升序查询
            Page<EstateUnitCard> returnPage = estateDoorCardService.selectWillUseCardPage(leftJoinWhere,page, wp);
            return R.ok().put("data", returnPage).putMpPageDescription().putDescription(EstateUnitCard.class);
        }
        if (cardState == 3) {//查询已发卡
            Page<EstateDoorCard> page = new Page<EstateDoorCard>(pageNum, pageSize);
            Wrapper<EstateDoorCard> wp = new EntityWrapper<EstateDoorCard>();
            if (null != communityId) {
                wp.eq("community_id", communityId);
            }
            if (null != unitId) {
                wp.eq("unit_id", unitId);
            }
            if (null != doorId) {
                wp.eq("door_id", doorId);
            }
            if (StringUtils.isNotBlank(cardNum)) {
                wp.like("cardNumTen", cardNum);
            }
            wp.orderBy("create_time",false);//根据发卡时间降序查询
            Page<EstateDoorCard> returnPage = estateDoorCardService.selectPage(page, wp);
            return R.ok().put("data", returnPage).putMpPageDescription().putDescription(EstateDoorCard.class);
        }
        return R.ok();
    }

    @ApiOperation(value = "添加/删除发卡记录-蓝牙发卡")
    @RequestMapping(value = "/manageDoorCardRecord", method = RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name = "manageType", value = "操作类型(1-添加,2-删除)", required = true, dataType = "int", paramType = "form"),
            @ApiImplicitParam(name = "cardNumSixteenStr", value = "卡号16进制字符串,英文逗号拼接", required = true, dataType = "string", paramType = "form"),
            @ApiImplicitParam(name = "doorId", value = "门id", required = true, dataType = "long", paramType = "form"),
            @ApiImplicitParam(name = "unitId", value = "单元id", required = true, dataType = "long", paramType = "form"),
            @ApiImplicitParam(name = "validTime", value = "有效期截止时间,默认100年(yyyyMMddHHmmss)", required = false, dataType = "string", paramType = "form"),
    })
    public R manageDoorCardRecord(Integer manageType, String cardNumSixteenStr, Long doorId, Long unitId, String validTime) {
        parameterIsNull(doorId, "门id不能为空");
        parameterIsNull(manageType, "操作类型不能为空");
        parameterIsNull(cardNumSixteenStr, "卡号不能为空");
        if (manageType != 1 && manageType != 2) {
            return R.error(400, "操作类型出错");
        }
        String[] cardNumSixteenArr = cardNumSixteenStr.split(",");
        Date nowDate = new Date();
        EntranceDoor door = entranceDoorService.selectById(doorId);
        parameterIsNull(door, "未查询到门信息");
        /*==================添加=====================================*/
        if (manageType == 1) {
            parameterIsNull(unitId, "单元id不能为空");
            try {
                if (!door.getDoorType().equals(1)) {//不是大门
                    if (!door.getUnitId().equals(unitId)) {
                        return R.error("门信息和单元信息不匹配");
                    }
                }
                if(door.getIsHaveLock()==null||door.getIsHaveLock()!=1){
                    return R.error("门尚未绑定锁设备");
                }
            } catch (NullPointerException ex) {
                return R.error("门信息错误，请联系物业管理员");
            }
            Date validDate = null;
            if (StringUtils.isBlank(validTime)) {
                validDate = DateUtil.addDate(nowDate, 1, 100);//获取当前时间 加上 100年
            }
            if (StringUtils.isNotBlank(validTime)) {
                validDate = DateUtil.stringToDate(validTime);
                if (validDate == null) {
                    return R.error(400, "有效期时间格式错误");
                }
                if (DateUtil.getDayBetween(new Date(), validDate) < 2) {// 当前时间 和 有效时间 间隔天数小于1天
                    return R.error(400, "有效期时间必须在2天以上");
                }
            }
            Wrapper<EstateUnitCard> unitCardWp = new EntityWrapper<EstateUnitCard>();
            unitCardWp.eq("unit_id", unitId);
            unitCardWp.in("card_num_sixteen", cardNumSixteenArr);
            List<EstateUnitCard> unitCardList = estateUnitCardService.selectList(unitCardWp);
            if (unitCardList == null || unitCardList.isEmpty()) {
                return R.error(400, "未查询到卡片录入记录");
            }
            if (!door.getCommunityId().equals(unitCardList.get(0).getCommunityId())) {
                return R.error(400, "门信息和卡片信息不匹配");
            }
            Wrapper<EstateDoorCard> existDoorCardWp = new EntityWrapper<EstateDoorCard>();
            existDoorCardWp.eq("door_id", doorId);
            existDoorCardWp.in("card_num_sixteen", cardNumSixteenArr);
            List<EstateDoorCard> existDoorCardList = estateDoorCardService.selectList(existDoorCardWp);
            Map<String, Object> existDoorCardMap = new HashMap<String, Object>();
            if (existDoorCardList != null && !existDoorCardList.isEmpty()) { // 卡片已下发的
                for (int x = 0; x < existDoorCardList.size(); x++) {
                    existDoorCardMap.put(existDoorCardList.get(x).getCardNumSixteen(), true);
                    existDoorCardList.get(x).setValidTime(validDate);//修改 有效时间
                    existDoorCardList.get(x).setCreateTime(nowDate);
                }
                estateDoorCardService.updateBatchById(existDoorCardList);
            }
            List<EstateDoorCard> insertDoorCardList = new ArrayList<EstateDoorCard>();
            for (int x = 0; x < unitCardList.size(); x++) {
                if (null == existDoorCardMap.get(unitCardList.get(x).getCardNumSixteen())) {//判断 卡片未下发的
                    EstateDoorCard doorCard = new EstateDoorCard();
                    doorCard.setCardNumSixteen(unitCardList.get(x).getCardNumSixteen());
                    doorCard.setCardNumTen(unitCardList.get(x).getCardNumTen());
                    doorCard.setCommunityId(unitCardList.get(x).getCommunityId());
                    doorCard.setCommunityName(unitCardList.get(x).getCommunityName());
                    doorCard.setUnitId(unitCardList.get(x).getUnitId());
                    doorCard.setUnitName(unitCardList.get(x).getUnitName());
                    doorCard.setCreateTime(nowDate);
                    doorCard.setValidTime(validDate);
                    doorCard.setDoorId(door.getDoorId());
                    doorCard.setDoorName(door.getDoorName());
                    insertDoorCardList.add(doorCard);
                }
            }
            if (!insertDoorCardList.isEmpty()) {
                estateDoorCardService.insertBatch(insertDoorCardList);
                estateDoorCardService.clearPreKeyCache("estateUnitCard");
            }
            //删除 在排队进行远程发卡的卡片
            estateLockCardService.delete(new EntityWrapper<EstateLockCard>().eq("door_id",doorId).in("card_num_sixteen",cardNumSixteenArr));
        }
    /*==================删除=====================================*/
        if (manageType == 2) {
            Wrapper<EstateDoorCard> existDoorCardWp = new EntityWrapper<EstateDoorCard>();
            existDoorCardWp.eq("door_id", doorId);
            existDoorCardWp.in("card_num_sixteen", cardNumSixteenArr);
            estateDoorCardService.delete(existDoorCardWp);
            estateDoorCardService.clearPreKeyCache("estateUnitCard");
        }
        return R.ok();
    }


    @ApiOperation(value = "远程发卡-每次下发500张")
    @RequestMapping(value = "/remoteSendFiveHundredCardToLock",method =RequestMethod.POST)
    @ApiImplicitParams({
            @ApiImplicitParam(name="doorId",value="门id",required = false,dataType = "long",paramType="form"),
            @ApiImplicitParam(name="unitId",value="单元id",required = false,dataType = "long",paramType="form"),
            @ApiImplicitParam(name="sendCardNum",value="本次发卡数量(最多500,默认500)",required = false,dataType = "int",paramType="form"),
            @ApiImplicitParam(name = "validTime", value = "有效期时间,默认10年(yyyyMMddHHmmss)", required = false, dataType = "string", paramType = "form"),
    })
    public R remoteSendFiveHundredCardToLock(Long unitId,Long doorId,String validTime,Integer sendCardNum){
        parameterIsNull(unitId,"请选择单元");
        parameterIsNull(doorId,"请选择门");
        if(sendCardNum==null||sendCardNum<1||sendCardNum>500){
            sendCardNum =500;
        }
        Date validDate = null;
        Date nowDate = new Date();
        if (StringUtils.isBlank(validTime)) {
            validDate = DateUtil.addDate(nowDate, 1, 10);//获取当前时间 加上 100年
        }
        if (StringUtils.isNotBlank(validTime)) {
            validDate = DateUtil.stringToDate(validTime);
            if (validDate == null) {
                return R.error(400, "有效期时间格式错误");
            }
            if (DateUtil.getDayBetween(new Date(), validDate) < 2) {// 当前时间 和 有效时间 间隔天数小于1天
                return R.error(400, "有效期时间必须在2天以上");
            }
        }
        EntranceDoor door = entranceDoorService.selectById(doorId);
        parameterIsNull(door, "未查询到门信息");
        if(door.getDoorType()!=1){
            if(!door.getUnitId().equals(unitId)){
                return R.error(400,"门信息与单元信息匹配出错");
            }
        }
        if(door.getDoorType()==1){
            UnitBuilding unit =unitBuildingService.selectById(unitId);
            if(!door.getCommunityId().equals( unit.getCommunityId() )){
                return R.error(400,"门信息与单元信息匹配出错");
            }
        }
        /*==验证设备==*/
        Map<String,Object> lockMap = daHaoLockUtil.checkDeviceIsOnLine(null,doorId);
        if(lockMap==null){
            return  R.error(400,"门尚未绑定设备");
        }
        if(lockMap.get("isOnLine").toString().equals("false")){
            return  R.error(400,"设备不在线");
        }
        List<EstateLockCard> lockCardList = estateLockCardService.selectListByEqSn(lockMap.get("eqSn").toString().trim());
        if(lockCardList!=null&&!lockCardList.isEmpty()){
            daHaoLockUtil.sendFiveHundredCard(lockMap,lockCardList);
            return  R.error(400,"上一批卡片尚未下发完成,正在下发");
        }else{
             /*==查询卡片==*/
            String leftJoinWhere ="";
            Wrapper<EstateUnitCard> unitCardListWp = new EntityWrapper<EstateUnitCard>();
            unitCardListWp.eq("euc.community_id", door.getCommunityId());
            if (unitId != null) {
                unitCardListWp.eq("euc.unit_id", unitId);
            }
            if (null != doorId) {
//                unitCardListWp.eq("edc.door_id", doorId);
                leftJoinWhere= " and edc.door_id = "+doorId;
            }
            unitCardListWp.and("edc.door_card_id is null");
            unitCardListWp.orderBy("euc.create_time",true);//根据录入时间升序查询
            unitCardListWp.last(" LIMIT "+sendCardNum);
            List<EstateUnitCard> unitCardList = estateDoorCardService.selectWillUseCardList(leftJoinWhere,unitCardListWp);
            if(unitCardList==null||unitCardList.isEmpty()){
                return R.error(400, "暂无卡片可以下发,请先录入卡片");
            }
            List<EstateLockCard> lockCards = new ArrayList<EstateLockCard>();
            for(int x=0;x<unitCardList.size();x++){
                EstateLockCard lockCard = new EstateLockCard();
                lockCard.setCardNumSixteen(unitCardList.get(x).getCardNumSixteen());
                lockCard.setCardNumTen(unitCardList.get(x).getCardNumTen());
                lockCard.setCommunityId(unitCardList.get(x).getCommunityId());
                lockCard.setCommunityName(unitCardList.get(x).getCommunityName());
                lockCard.setDoorId(door.getDoorId());
                lockCard.setDoorName(door.getDoorName());
                lockCard.setEqPswd(lockMap.get("eqPswd").toString());
                lockCard.setEqSn(lockMap.get("eqSn").toString());
                lockCard.setUnitId(unitCardList.get(x).getUnitId());
                lockCard.setUnitName(unitCardList.get(x).getUnitName());
                lockCard.setValidTime(validDate);
                lockCards.add(lockCard);
            }
            estateLockCardService.insertBatch(lockCards);
            daHaoLockUtil.sendFiveHundredCard(lockMap,lockCards);
        }
        return R.ok("卡片下发中");
    }
}
